#include <tchar.h>
#include <time.h>
#include <direct.h>
#include <algorithm>
#include "log.h"
#include "memrec.h"
#define new DBG_NEW


tLog::tLog():
m_LogFile(INVALID_HANDLE_VALUE),
m_LayoutFlag(0),
m_level(0)
{
	lstrcpy(leveltext[LV_FORCE],		_T("FORCE")); 
	lstrcpy(leveltext[LV_ERROR],    _T("ERROR"));
	lstrcpy(leveltext[LV_WARNING],  _T("WARNING"));
	lstrcpy(leveltext[LV_INFO],     _T("INFO"));
	lstrcpy(leveltext[LV_DEBUG],    _T("DEBUG"));

}

tLog::~tLog()
{
	Close();
}

int tLog::Open(std::wstring filename, DWORD layout, DWORD level)
{
	std::wstring::iterator it_slash = filename.begin();
	while (it_slash != filename.end())
	{
		it_slash = std::find(it_slash, filename.end(), L'\\');
		if (it_slash != filename.end())
		{
			std::wstring dir = filename.substr(0, it_slash - filename.begin());
			_wmkdir(dir.c_str());
			it_slash++;
		}
	}
	m_LogFile = CreateFileW(filename.c_str(), 
							GENERIC_WRITE, 
							FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
							NULL, 
							OPEN_ALWAYS, 
							FILE_ATTRIBUTE_NORMAL, 
							0);
	if (m_LogFile != INVALID_HANDLE_VALUE)
	{
#ifdef _UNICODE
		DWORD err = GetLastError();
		if (err != ERROR_ALREADY_EXISTS)
		{
			wchar_t UnicodeFlag = 0XFEFF;
			DWORD Written = 0;
			// Write uncode flag to it.
			WriteFile(m_LogFile, &UnicodeFlag, 2, &Written, NULL);
		}
#endif
		// Goto tail of the file.
		SetFilePointer(m_LogFile, 0, 0, FILE_END);
		m_LogFileName = filename;
		m_LayoutFlag = layout;
		m_level = level;
		Log(LV_FORCE, _T("------------Log4Update start.-------------"));
		return 0;
	}
	else
		return -1;
}

void tLog::Log(DWORD level, const TCHAR * LogText)
{
	if (level > m_level)
		return;
	if (m_LogFile != INVALID_HANDLE_VALUE)
	{
		// printf time.
		time_t t = time(NULL);
		TCHAR time[32];
		_tctime_s(time, 32, &t);
		time[lstrlen(time)-1] = 0;
		TCHAR out[512];
		_stprintf_s(out, 512, _T("[%s]%s: %s\r\n"), time, leveltext[level], LogText);
		out[511] = 0;
		DWORD Written = lstrlen(out)*sizeof(TCHAR);
		WriteFile(m_LogFile, out, Written, &Written, NULL);
		FlushFileBuffers(m_LogFile);
	}
}

void tLog::Close()
{
	Log(LV_FORCE, _T("------------Log4Update end.-------------"));
	if (m_LogFile != INVALID_HANDLE_VALUE)
		CloseHandle(m_LogFile);
	m_LogFile = INVALID_HANDLE_VALUE;

}